package com.tio.demo;

import com.tio.demo.HelloPacket;
import org.tio.core.Aio;
import org.tio.core.ChannelContext;
import org.tio.core.GroupContext;
import org.tio.core.exception.AioDecodeException;
import org.tio.core.intf.Packet;
import org.tio.server.intf.ServerAioHandler;

import java.nio.ByteBuffer;

/**
 * Author      : liyuemin
 * Time        : 2017/12/14 9:35
 * Description :
 */
public class HelloServerAioHandler implements ServerAioHandler{

    /**
    * @Description : 解码：把接受到的ByteBuffer,解码成应用可以识别的业务消息包
     *                 总的消息结构：消息头+消息体
     *                 消息头结构4个字节，存储消息体的长度
     *                 对象的json串的byte[]
    * @param       : [byteBuffer, channelContext]
    * @return      : org.tio.core.intf.Packet
    * @author      : XieMing
    * @date        : 2017/12/14
    */
    @Override
    public Packet decode(ByteBuffer byteBuffer, ChannelContext channelContext) throws AioDecodeException {
        int readablelength = byteBuffer.limit()-byteBuffer.position();//缓冲区限制-缓冲区位置
        if(readablelength< HelloPacket.HEADER_LENGTH){
            return null;
        }
        //读取消息体的长度
        int bodylength = byteBuffer.getInt();
        if(bodylength<0){
            throw new AioDecodeException("bodylength["+"] is not right,remote:"+channelContext.getClientNode());
        }
        //计算本次数据的长度
        int neededLenght = HelloPacket.HEADER_LENGTH + bodylength;
        //收到的消息是否足够组包
        int isDataEnough = readablelength-neededLenght;
        if(isDataEnough<0){
            return null;
        }else{//组包成功
            HelloPacket imPacket = new HelloPacket();
            if(bodylength>0){
                byte[] dst = new byte[bodylength];
                byteBuffer.get(dst);
                imPacket.setBody(dst);
            }
            return imPacket;
        }
    }
    /**
    * @Description : 编码：把业务消息包编码为可发送的byteBuffer
     *                 总的消息结构：消息头+消息体
     *                 消息头结构：4个字节，存储消息体的长度
     *                 消息体结构：对象的json串byte[]
    * @param       : [packet, groupContext, channelContext]
    * @return      : java.nio.ByteBuffer
    * @author      : XieMing
    * @date        : 2017/12/14
    */
    @Override
    public ByteBuffer encode(Packet packet, GroupContext groupContext, ChannelContext channelContext) {
        HelloPacket helloPacket = (HelloPacket) packet;
        byte[] body = helloPacket.getBody();//获取消息体
        int bodylength = 0;
        if(body!= null){
            bodylength = body.length;
        }
        //byteBuffer的总长度 = 消息头长度+消息体长度
        int allLength = HelloPacket.HEADER_LENGTH + bodylength;
        //创建一个新的ByteBuffer
        ByteBuffer buffer = ByteBuffer.allocate(allLength);
        //设置字节序
        buffer.order(groupContext.getByteOrder());
        //写入消息头
        buffer.putInt(bodylength);
        //写入消息体
        buffer.put(body);
        return buffer;
    }
    /**
    * @Description : 处理消息
    * @param       : [packet, channelContext]
    * @return      : void
    * @author      : XieMing
    * @date        : 2017/12/14
    */
    @Override
    public void handler(Packet packet, ChannelContext channelContext) throws Exception {
        HelloPacket helloPacket = (HelloPacket) packet;
        byte[] body  = helloPacket.getBody();
        if(body!= null){
            String str = new String(body,HelloPacket.CHARSTER);
            System.out.println("收到消息"+ str);
            HelloPacket respacket = new HelloPacket();
            respacket.setBody(("收到了你的消息，你的消息是："+str).getBytes(HelloPacket.CHARSTER));
            Aio.send(channelContext,respacket);
        }
        return ;
    }
}
